package com.workcell.workdata.xthings.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.workcell.workdata.xthings.constant.HardwareStateEnum;
import com.workcell.workdata.xthings.constant.SerialCommunicationTypeEnum;
import com.workcell.workdata.xthings.constant.SerialWorkingModeEnum;
import com.workcell.workdata.xthings.dto.CodeChainnumVo;
import com.workcell.workdata.xthings.entity.BaseSerialDevice;
import com.workcell.workdata.xthings.entity.CodeChainnum;
import com.workcell.workdata.xthings.entity.CodeSerialDevice;
import com.workcell.workdata.xthings.mapper.CodeSerialDeviceMapper;
import com.workcell.workdata.xthings.service.BaseSerialDeviceService;
import com.workcell.workdata.xthings.service.CodeSerialDeviceService;
import lombok.RequiredArgsConstructor;
import org.springframework.scheduling.support.CronExpression;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Admin
 * @description 针对表【t_code_serial_device】的数据库操作Service实现
 * @createDate 2023-03-18 09:33:31
 */
@Service
@RequiredArgsConstructor
public class CodeSerialDeviceServiceImpl extends ServiceImpl<CodeSerialDeviceMapper, CodeSerialDevice>
        implements CodeSerialDeviceService {
    private final BaseSerialDeviceService baseSerialDeviceService;
    public static final String DEFAULT_CRON_EXPRESSION = "0/30 * * * * ?";
    public static final Integer DEFAULT_BAUD_RATE = 9600;
    public static final String DEFAULT_WORKING_MODE = SerialWorkingModeEnum.STANDARD.getCode();
    public static final String DEFAULT_PUBLISH_TOPIC_4G = "";
    public static final String DEFAULT_SUBSCRIBE_TOPIC_4G = "";
    public static final String DEFAULT_PUBLISH_TOPIC_NA111 = "";
    public static final String DEFAULT_SUBSCRIBE_TOPIC_E841 = "";

    /**
     * 保存二维码快照信息
     *
     * @param codeChainnum
     * @return
     */
    @Override
    public boolean saveCodeBaseInfo(CodeChainnum codeChainnum, CodeChainnumVo.SaveChainNumVo saveChainNumVo) {
        // 查询硬件信息
        LambdaQueryWrapper<BaseSerialDevice> baseSerialDeviceCondition = new QueryWrapper<BaseSerialDevice>().lambda()
                .eq(BaseSerialDevice::getId, codeChainnum.getBaseId());
        BaseSerialDevice baseSerialDevice = baseSerialDeviceService.getOne(baseSerialDeviceCondition);
        if (ObjectUtil.isEmpty(baseSerialDevice)) {
            return false;
        }

        // 校验Cron表达式是否合法
        String cronExpression = saveChainNumVo.getCronExpression();
        Assert.isTrue(
                cronExpression == null || CronExpression.isValidExpression(cronExpression),
                "非法的Cron表达式:{}",
                cronExpression
        );
        // 添加二维码快照信息
        CodeSerialDevice saveBean = new CodeSerialDevice();
        BeanUtil.copyProperties(baseSerialDevice, saveBean, "createBy", "createTime", "updateBy", "updateTime");
        saveBean.setCodeId(codeChainnum.getCodeId())
                .setChainNum(codeChainnum.getChainNum())
                .setDeviceNo(codeChainnum.getDeviceNo())
                .setDtId(String.valueOf(baseSerialDevice.getId()))
                .setDtName(baseSerialDevice.getName())
                .setMacAddress(saveChainNumVo.getMacAddress())
                .setCronExpression(StrUtil.emptyToDefault(cronExpression, DEFAULT_CRON_EXPRESSION))
                .setBaudRate(ObjectUtil.defaultIfNull(saveChainNumVo.getBaudRate(), DEFAULT_BAUD_RATE))
                .setWorkingMode(StrUtil.emptyToDefault(saveChainNumVo.getWorkingMode(), DEFAULT_WORKING_MODE))
                .setPublishTopic(StrUtil.emptyToDefault(saveChainNumVo.getPublishTopic(), SerialCommunicationTypeEnum.generatePublishTopic(saveChainNumVo.getDeviceNo(),saveChainNumVo.getHardwareName())))
                .setSubscribeTopic(StrUtil.emptyToDefault(saveChainNumVo.getSubscribeTopic(), SerialCommunicationTypeEnum.generateSubscribeTopic(saveChainNumVo.getDeviceNo(), saveChainNumVo.getHardwareName())));
        return this.save(saveBean);
    }

    /**
     * 查询硬件基本信息
     *
     * @param baseIds
     * @return
     */
    @Override
    public Object getHardwareBase(String baseIds) {
        List<String> baseList = Arrays.asList(baseIds.split(","));
        LambdaQueryWrapper<BaseSerialDevice> baseSerialDeviceCondition = new QueryWrapper<BaseSerialDevice>().lambda()
                .in(CollectionUtil.isNotEmpty(baseList), BaseSerialDevice::getId, baseList);
        return baseSerialDeviceService.list(baseSerialDeviceCondition);
    }

    /**
     * 获取硬件清单
     *
     * @return
     */
    @Override
    public List<JSONObject> getHardwareList() {
		LambdaQueryWrapper<BaseSerialDevice> lambdaQueryWrapper = Wrappers.lambdaQuery(BaseSerialDevice.class);
		lambdaQueryWrapper.eq(BaseSerialDevice::getState, HardwareStateEnum.INUSE.getCode());
        return baseSerialDeviceService.list(lambdaQueryWrapper).stream().map(i -> {
            JSONObject resultBean = new JSONObject();
            resultBean.put("baseId", String.valueOf(i.getId()));
            resultBean.put("manufacturer", i.getManufacturer());
            resultBean.put("hardwareName", i.getName());
            return resultBean;
        }).collect(Collectors.toList());
    }
}




